package
{
   import com.greensock.TweenMax;
   import com.greensock.easing.Linear;
   import com.greensock.plugins.FramePlugin;
   import com.greensock.plugins.TweenPlugin;
   
   import flash.display.FrameLabel;
   import flash.display.MovieClip;
   
   public class TweenMax2
   {
      /**
       * Make the moveiclip-instance paly to the target farme.
       * @param $target       Must be a MovieClip.
       * @param $newFrame     Mostly a interger, but 'totalFrames' means make it play to its totalFrames.
       * @param param         Other configuration, see http://www.greensock.com for detail.
       * @return              TweenMax object.
       */
      public static function frameTo($target:Object, $newFrame:*, param:Object = null):TweenMax
      {
         var target:MovieClip = MovieClip($target);
         if (!target) return null;
         if (!target.stage) return null;
         
         // active plugin
         TweenPlugin.activate([FramePlugin]);
         
         // duration
         var dur:Number;
         var newFrame:int;
         if (typeof($newFrame) == 'string' && $newFrame == 'totalFrames')
         {
            newFrame = target.totalFrames;
            dur = Math.abs(target.totalFrames - target.currentFrame) / target.stage.frameRate;
         }
         else
         {
            newFrame = int($newFrame);
            dur = Math.abs(int(newFrame) - target.currentFrame) / target.stage.frameRate;
         }
         // In order to fix a issue that happens on fastly mouse-over and then mouse-out. It'll stop on the wrong frame
         if (dur == 0)
         {
            dur = 0.01;
         }
         
         // parameter
         var params:Object = param || new Object();
         params.frame = newFrame;
         params.ease = Linear.easeNone;
         
         return TweenMax.to(target, dur, params);
      }
      
      /**
       * Make the movieclip-instance play to the target label.
       * @param $target       Must be a MovieClip.
       * @param label         Frame label.
       * @param param         Other configuration, see http://www.greensock.com for detail.
       * @return              TweenMax object.
       */
      public static function labelTo($target:Object, label:String, param:Object = null):TweenMax
      {
         var target:MovieClip = MovieClip($target);
         if (!target) return null;
         if (!target.stage) return null;
         
         return TweenMax2.frameTo(target, getFrameByLabel(target, label), param);
      }
      
      // --------------------- LINE ---------------------
      
      /**
       * To get the frame of the target label.
       * @param $target       Must be a MovieClip.
       * @param label         Frame label.
       * @return              The frame.(interger)
       */
      public static function getFrameByLabel($target:Object, label:String):int
      {
         var target:MovieClip = MovieClip($target);
         if (!target) return 1;
         
         var ret:int = 1;
         var ln:int = target.currentLabels.length;
         
         for (var i:int = 0; i < ln; ++i)
         {
            var lb:FrameLabel = target.currentLabels[i] as FrameLabel;
            if (lb.name == label)
            {
               ret = lb.frame;
               break;
            }
         }
         
         return ret;
      }

      /**
       * Is the currentframe on the given timeline label.
       * @param $target       Must be a MovieClip.
       * @param label         Frame label.
       * @return              True or false.
       */
      public static function isOnLabel($target:Object, label:String):Boolean
      {
         var target:MovieClip = MovieClip($target);
         if (!target) return false;
         
         var lb_frame:int = getFrameByLabel($target, label);
         return target.currentFrame == lb_frame;
      }

      // ################### protected ##################
      
      // #################### private ###################
      
      // --------------------- LINE ---------------------
      
   }
   
}